﻿using System;
using System.Collections;
using System.Collections.Generic;
using Glue;
using GlueTests.Tools;
using Xunit;

namespace GlueTests.MapperTests
{
    public class When_mapping_between_custom_enumerables
    {
        private readonly Mapping<StandtardPerson, CustomPerson> mapping;

        public class StandtardPerson
        {
            public IList<String> IList { get; set; }
        }

        public class CustomPerson
        {
            public CustomList<String> CustomList { get; set; }
        }

        public When_mapping_between_custom_enumerables()
        {
            mapping = new Mapping<StandtardPerson, CustomPerson>();
            mapping.Relate(from => from.IList, to => to.CustomList);
        }

        [Fact]
        public void Should_map_to_customList()
        {
            var fromPerson = new StandtardPerson { IList = new List<string> { "1", "2", "3" } };
            var toPerson = mapping.Map(fromPerson, new CustomPerson());

            Assert.Equal(fromPerson.IList, toPerson.CustomList, new CollectionEquivalenceComparer<String>());
        }

        [Fact]
        public void Should_map_from_customList()
        {
            var fromPerson = new CustomPerson { CustomList = new CustomList<string>{ "1", "2", "3" } };
            var toPerson = mapping.Map(fromPerson, new StandtardPerson());

            Assert.Equal(fromPerson.CustomList, toPerson.IList, new CollectionEquivalenceComparer<String>());
        }


        #region CustomList
        public class CustomList<T> : IList<T>, IList
        {
            private readonly List<T> list;
            public CustomList() : this(new List<T>()) { }

            private CustomList(List<T> list)
            {
                this.list = list;
            }

            public IEnumerator<T> GetEnumerator() { return list.GetEnumerator(); }
            IEnumerator IEnumerable.GetEnumerator() { return list.GetEnumerator(); }

            public void Add(T item)
            {
                list.Add(item);
            }

            public int Add(object value)
            {
                Add((T)value);
                return list.Count - 1;
            }

            public bool Contains(object value)
            {
                throw new System.NotImplementedException();
            }

            public void Clear()
            {
                throw new System.NotImplementedException();
            }

            public int IndexOf(object value)
            {
                throw new System.NotImplementedException();
            }

            public void Insert(int index, object value)
            {
                throw new System.NotImplementedException();
            }

            public void Remove(object value)
            {
                throw new System.NotImplementedException();
            }

            public bool Contains(T item)
            {
                throw new System.NotImplementedException();
            }

            public void CopyTo(T[] array, int arrayIndex)
            {
                list.CopyTo(array,arrayIndex);
            }

            public bool Remove(T item)
            {
                throw new System.NotImplementedException();
            }

            public void CopyTo(Array array, int index)
            {
                throw new System.NotImplementedException();
            }

            public int Count
            {
                get { return list.Count; }
            }

            public object SyncRoot
            {
                get { throw new System.NotImplementedException(); }
            }

            public bool IsSynchronized
            {
                get { throw new System.NotImplementedException(); }
            }

            object IList.this[int index]
            {
                get { throw new System.NotImplementedException(); }
                set { throw new System.NotImplementedException(); }
            }

            public bool IsReadOnly
            {
                get { throw new System.NotImplementedException(); }
            }

            public bool IsFixedSize
            {
                get { throw new System.NotImplementedException(); }
            }

            public int IndexOf(T item)
            {
                throw new System.NotImplementedException();
            }

            public void Insert(int index, T item)
            {
                throw new System.NotImplementedException();
            }

            public void RemoveAt(int index)
            {
                throw new System.NotImplementedException();
            }

            public T this[int index]
            {
                get { throw new System.NotImplementedException(); }
                set { throw new System.NotImplementedException(); }
            }
        }
        #endregion
    }
}
